﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ControlPoint.ControlAPI {
    public class Configuration {

        [XmlIgnore()]
        public Dictionary<string, Device> _devices;

        [XmlIgnore()]
        public Dictionary<string, DeviceController> _controllers;

        [XmlIgnore()]
        public SerializableDictionary<String, String> Events { get; set; }


        [XmlArray("Controllers")]
        [XmlArrayItem("Controller")]
        public List<List<Setting>> Controllers {
            get {
                List<List<Setting>> sll = new List<List<Setting>>();
                List<Setting> sl;
                foreach (DeviceController d in _controllers.Values) {
                    sl = new List<Setting>();
                    foreach (Setting s in d.Settings.Settings.Values) {
                        sl.Add(s);
                    }
                    sll.Add(sl);
                }
                return sll;
            }
            set {
                Console.WriteLine(value.Count);
                return;
            }
        }

        [XmlArray("Devices")]
        [XmlArrayItem(ElementName = "Device")]
        public List<List<Setting>> Devices {
            get {
                List<List<Setting>> sll = new List<List<Setting>>();
                List<Setting> sl;
                foreach (Device d in _devices.Values) {
                    sl = new List<Setting>();
                    foreach (Setting s in d.Settings.Settings.Values) {
                        sl.Add(s);
                    }
                    sll.Add(sl);
                }
                return sll;
            }
            set { }
        }

        public Configuration()  {
            this._devices = new Dictionary<string, Device>();
            this._controllers = new Dictionary<string, DeviceController>();
            this.Events = new SerializableDictionary<string, string>();
        }


        public void SaveConfiguration() {


            XmlSerializer serializer;

            serializer = new XmlSerializer(typeof(Configuration));

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "  ";
            settings.CheckCharacters = false;
            settings.NewLineOnAttributes = true;
            settings.ConformanceLevel = ConformanceLevel.Document;

            //Using XmlWriter to create xml file.
            using (XmlWriter writer = XmlWriter.Create("Configuration.xml", settings)) {


                serializer.Serialize(writer, this);

                writer.Flush();
            }
            Console.ReadLine();
        }

        public void LoadConfiguration() {

            try {

                XmlRootAttribute xRootController = new XmlRootAttribute();
                xRootController.ElementName = "Controller";
                XmlSerializer serializerController = new XmlSerializer(typeof(List<Setting>), xRootController);

                XmlRootAttribute xRootDevice = new XmlRootAttribute();
                xRootDevice.ElementName = "Device";
                XmlSerializer serializerDevice = new XmlSerializer(typeof(List<Setting>), xRootDevice);


                List<List<Setting>> controllers = new List<List<Setting>>();
                List<List<Setting>> devices = new List<List<Setting>>();

                XmlTextReader txtReader = new XmlTextReader("Configuration.xml");
                XmlReaderSettings settings = new XmlReaderSettings();
                settings.ValidationType = ValidationType.Schema;
                XmlReader reader = XmlReader.Create(txtReader, settings);

                while (reader.Read()) {
                    switch (reader.NodeType) {
                        case XmlNodeType.Element:
                            if (reader.Name == "Controller") {
                                controllers.Add((List<Setting>)serializerController.Deserialize(reader));
                            }
                            if (reader.Name == "Device") {
                                devices.Add((List<Setting>)serializerDevice.Deserialize(reader));

                            }
                            break;
                    }
                }

                reader.Close();
                SettingsList sl;

                DeviceController dc;
                foreach (List<Setting> ls in controllers) {
                    sl = new SettingsList(ls);
                    string className = (string)sl.GetSetting("type").Value;
                    Console.WriteLine("CREATE: " + className);
                    dc = (DeviceController)Activator.CreateInstance(Type.GetType(className), new object[] { sl });
                    this._controllers.Add(dc.ID, dc);
                }

                Device d;
                foreach (List<Setting> ls in devices) {
                    sl = new SettingsList(ls);
                    string className = (string)sl.GetSetting("type").Value;
                    string controllerId = (string)sl.GetSetting("controllerId").Value;
                    Console.WriteLine("CREATE:: " + className);
                    d = (Device)Activator.CreateInstance(Type.GetType(className), new object[] { this._controllers[controllerId], sl });
                    this._devices.Add(d.ID, d);
                }
            } catch (Exception e) {
                Console.WriteLine("Exception");
                Console.WriteLine (e.ToString());

            }
        }

        public void SaveEvents() {


            XmlRootAttribute xRoot = new XmlRootAttribute();
            xRoot.ElementName = "Events";

            XmlSerializer serializer;

            serializer = new XmlSerializer(typeof(SerializableDictionary<string, string>), xRoot);

            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "  ";
            settings.CheckCharacters = false;
            settings.NewLineOnAttributes = true;
            settings.ConformanceLevel = ConformanceLevel.Document;

            //Using XmlWriter to create xml file.
            using (XmlWriter writer = XmlWriter.Create("Events2.xml", settings)) {


                serializer.Serialize(writer, this.Events);

                writer.Flush();
            }

        }

        public void LoadEvents() {
            //SerializableDictionary<string, string> events;

            XmlRootAttribute xRoot = new XmlRootAttribute();
            xRoot.ElementName = "Events";

            XmlSerializer serializer;

            serializer = new XmlSerializer(typeof(SerializableDictionary<string, string>), xRoot);

            // To read the file, creates a FileStream.
            System.IO.FileStream myFileStream = new System.IO.FileStream("Events.xml", System.IO.FileMode.Open);
            this.Events = (SerializableDictionary<string, string>)serializer.Deserialize(myFileStream);
            myFileStream.Close();
        }

    }
}
